<template>
  <div class="app-container">
    <el-form :model="formData" ref="formDataRef" :rules="formDataRules" label-position="left">
      <el-row :gutter="20">
        <el-col :span="6">
          <el-form-item label="菜单名称" prop="name">
            <el-input v-model="formData.name" placeholder="菜单名称" clearable style="width: 100%"></el-input>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="24">
          <ActionButtons @reset="handleReset" @query="query">
            <el-button type="primary" size="small" @click="handleAddMenu">新增菜单</el-button>
          </ActionButtons>
        </el-col>
      </el-row>
    </el-form>
    <BaseTable :tableColumns="tableColumns" :tableData="tableData" :options="tableOptions" :total="pages.total" v-model:page-num="pages.pageNum" v-model:page-size="pages.pageSize" @turn-on="query">
      <template v-slot:operation="{ row }">
        <el-button type="primary" text @click="handleTableItemEdit(row)">编辑</el-button>
        <el-button type="danger" text @click="handleTableItemDel(row)">删除</el-button>
      </template>
      <template v-slot:statusDetail="{ row }">
        <el-tag :type="row.status === '1' ? 'success' : 'danger'" size="small">
          {{ row.statusDetail }}
        </el-tag>
      </template>
      <template v-slot:menuName="{ row }">
        {{ row.meta.title }}
      </template>
      <template v-slot:icon="{ row }">
        <el-icon v-if="row.icon && row.icon !== '#'">
          <component :is="row.icon"></component>
        </el-icon>
      </template>
    </BaseTable>
    <Dialog ref="dialogRef" :title="dialogOptions.title" :width="dialogOptions.width" @close="handleDialogClose" @confirm="handleDialogConfirm">
      <template v-slot:content>
        <el-form :model="diaFormData" label-position="left" ref="diaFormDataRef" :rules="diaFormDataRules" label-width="150px">
          <el-form-item label="上级菜单" prop="parentId">
            <el-tree-select v-model="diaFormData.parentId" :data="menuParentTree" style="width: 100%" clearable check-strictly @change="handleTreeClick" placeholder="-- 上级目录 --"></el-tree-select>
          </el-form-item>
          <el-form-item label="菜单类型" prop="menuType">
            <el-radio-group v-model="diaFormData.menuType" :disabled="dialogOptions.openType === 2">
              <el-radio label="1">目录</el-radio>
              <el-radio label="2" :disabled="diaFormData.parentId === 0">菜单</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="菜单名称(英文描述)" prop="name">
            <el-input v-model="diaFormData.name" placeholder="菜单名称(英文描述)" clearable @input="handleNameInput"></el-input>
            <div class="form-tip">请使用大写字母开头的驼峰命名，例如：SystemMenu</div>
          </el-form-item>
          <el-form-item label="菜单名称(中文描述)" prop="meta.title">
            <el-input v-model="diaFormData.meta.title" placeholder="菜单名称(中文描述)" clearable></el-input>
          </el-form-item>
          <el-row>
            <el-col :span="12" v-if="diaFormData.menuType === '1'">
              <el-form-item label="菜单图标" prop="icon">
                <el-input v-model="diaFormData.meta.icon" placeholder="合理的图标名称" clearable>
                  <template #append>
                    <el-button @click="openIconSelector">
                      <el-icon><Search /></el-icon>
                    </el-button>
                  </template>
                </el-input>
                <el-icon v-if="diaFormData.meta.icon" style="width: 2em; height: 2em; margin-top: 8px">
                  <component :is="diaFormData.meta.icon"></component>
                </el-icon>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="显示排序" prop="order" class="ml-2">
                <el-input-number :min="0" v-model="diaFormData.order" placeholder="显示排序" clearable></el-input-number>
              </el-form-item>
            </el-col>
          </el-row>
          <el-form-item label="组件地址" prop="component" v-if="diaFormData.menuType === '2'">
            <el-input :disabled="diaFormData.parentId === 0" v-model="diaFormData.component" placeholder="组件地址" clearable></el-input>
          </el-form-item>
          <el-form-item label="路由地址" prop="path">
            <el-input v-model="diaFormData.path" placeholder="路由地址" clearable></el-input>
            <div class="form-tip">路由地址必须以 / 开头，例如：/system/menu</div>
          </el-form-item>
          <el-form-item label="菜单状态" prop="status">
            <el-radio-group v-model="diaFormData.status">
              <el-radio label="1">启用</el-radio>
              <el-radio label="0">停用</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-form>
      </template>
    </Dialog>

    <!-- 图标选择器弹窗 -->
    <el-dialog v-model="iconSelectorVisible" title="选择图标" width="60%" destroy-on-close>
      <div class="icon-search-container">
        <el-input v-model="iconSearchText" placeholder="搜索图标" clearable>
          <template #prefix>
            <el-icon><Search /></el-icon>
          </template>
        </el-input>
      </div>
      <div class="icon-container">
        <div v-for="item in filteredIconList" :key="item" class="icon-item" @click="handleChoose(item)">
          <el-icon>
            <component :is="item"></component>
          </el-icon>
          <div class="icon-name">{{ item }}</div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>
<script lang="ts" setup>
import { ref, reactive, computed } from "vue";
import FSMessage from "@/utils/message";
import type { FormInstance, FormRules } from "element-plus";
// BaseTable、ActionButtons、Dialog 组件已在 main.ts 中全局注册
import { IPaginationForm } from "@/types/http";
import { resetForm, validateForm, processMenuChildren } from "@/utils/tools";
import useHooksTable from "./useHooksTable";
import useHooksDialog from "./useHooksDialog";
import { getMenuListAllAPI, getMenuListChildrenAPI, updateMenuAPI, deleteMenuAPI, createMenuAPI } from "@/api/menu";
import { cloneDeep } from "lodash-es";

/* ------------------------------ variable ------------------------------ */
const formData = ref({
  name: ""
});
const dialogRef = ref();
const formDataRef = ref<FormInstance>();
const formDataRules = ref<FormRules>();
const diaFormDataRef = ref<FormInstance>();
const pages = ref<IPaginationForm>({
  pageSize: 20,
  pageNum: 1,
  total: 0
});
// 常用的Element Plus图标列表
const iconList = ref([
  "Plus",
  "Minus",
  "CirclePlus",
  "Search",
  "Female",
  "Male",
  "Aim",
  "House",
  "FullScreen",
  "Loading",
  "Link",
  "ChatDotRound",
  "ChatRound",
  "CircleCheck",
  "Edit",
  "Share",
  "Delete",
  "Setting",
  "View",
  "Hide",
  "Refresh",
  "Back",
  "ArrowLeft",
  "ArrowRight",
  "ArrowDown",
  "ArrowUp",
  "Bell",
  "Calendar",
  "CaretBottom",
  "CaretLeft",
  "CaretRight",
  "CaretTop",
  "Check",
  "Close",
  "CreditCard",
  "Document",
  "Download",
  "Expand",
  "Fold",
  "FullScreen",
  "Grid",
  "HomeFilled",
  "InfoFilled",
  "Location",
  "Lock",
  "Menu",
  "Message",
  "MoreFilled",
  "Notification",
  "Phone",
  "Picture",
  "PictureFilled",
  "Pointer",
  "Position",
  "Printer",
  "QuestionFilled",
  "Rank",
  "Remove",
  "Right",
  "Select",
  "Service",
  "SetUp",
  "Shop",
  "ShoppingBag",
  "ShoppingCart",
  "ShoppingCartFull",
  "Sort",
  "Star",
  "StarFilled",
  "Stopwatch",
  "SuccessFilled",
  "Switch",
  "Ticket",
  "Timer",
  "Tools",
  "Top",
  "TopLeft",
  "TopRight",
  "TrendCharts",
  "Trophy",
  "Upload",
  "User",
  "VideoCamera",
  "VideoCameraFilled",
  "Warning",
  "WarningFilled",
  "ZoomIn",
  "ZoomOut"
]);

// 图标选择器相关变量
const iconSelectorVisible = ref(false);
const iconSearchText = ref("");

// 根据搜索文本过滤图标列表
const filteredIconList = computed(() => {
  if (!iconSearchText.value) {
    return iconList.value;
  }
  return iconList.value.filter((icon) => icon.toLowerCase().includes(iconSearchText.value.toLowerCase()));
});

/**
 * @breif: 打开图标选择器弹窗
 */
const openIconSelector = () => {
  iconSelectorVisible.value = true;
  iconSearchText.value = "";
};

/**
 * @breif: 选择图标
 * @param {string} iconName 图标名称
 */
const handleChoose = (iconName: string) => {
  diaFormData.value.meta.icon = iconName;
  iconSelectorVisible.value = false;
};

const { tableColumns, tableData, tableOptions } = useHooksTable();
const { diaFormData, menuParentTree, diaFormDataRules } = useHooksDialog();

const dialogOptions = ref<any>({
  title: "新增菜单",
  openType: 1, // 1 新增 2 编辑
  width: "600px"
});
/* ------------------------------ function ------------------------------ */

/**
 * @breif: 重置
 * @return {*}
 */
const handleReset = () => {
  resetForm(formDataRef.value);
  query();
};

/**
 * @breif: 请求接口
 * @return {*}
 */
const query = async () => {
  try {
    const res = await getMenuListAllAPI({ ...pages.value, ...formData.value });
    res.data.list.forEach((item: any, index) => {
      // @ts-ignore
      item.index = index + 1 + (pages.value.pageNum - 1) * pages.value.pageSize;
      item.menuName = item.meta.title;
      item.icon = item.meta.icon;
      // 处理状态显示
      item.statusDetail = item.status === "1" ? "启用" : "停用";
    });
    tableData.value = res.data.list;
    pages.value.total = res.data.total;

    // 初始化菜单父级树数据
    if (!menuParentTree.value || menuParentTree.value.length === 0) {
      await initMenuParentTree();
    }
  } catch (e) {
    console.log(e);
  }
};

/**
 * @breif: 初始化菜单父级树数据
 * @return {*}
 */
const initMenuParentTree = async () => {
  try {
    const menusChildren = await getMenuListChildrenAPI({});
    menusChildren.data.push({
      menuId: 0,
      meta: {
        title: "主类目",
        icon: "Search"
      }
    });
    menuParentTree.value = processMenuChildren(menusChildren.data);
  } catch (e) {
    console.log(e);
  }
};

query();

/**
 * @breif: 新增菜单
 * @return {*}
 */
const handleAddMenu = async () => {
  try {
    dialogOptions.value.openType = 1;
    dialogOptions.value.title = "新增菜单";
    dialogRef.value.visiableDialog();
    resetForm(diaFormDataRef.value);
  } catch (e) {
    console.log(e);
  }
};

/**
 * @breif: 选择树中的某个节点
 * @param {*} value 节点数据（节点对应的value）
 * @return {*}
 */
const handleTreeClick = (value) => {
  if (value === 0) {
    diaFormData.value.menuType = "1";
    diaFormData.value.component = "Layout";
  }
};

/**
 * @breif: 处理菜单名称输入，自动转换为路由地址
 * @param {string} value 输入的菜单名称
 * @return {*}
 */
const handleNameInput = (value: string) => {
  if (value) {
    // 将驼峰命名转换为短横线命名并添加前缀斜杠
    const path = "/" + value.replace(/([A-Z])/g, "-$1").toLowerCase();
    // 去除开头可能出现的多余短横线
    diaFormData.value.path = path.replace(/^\/-/, "/");
  }
};
const handleDialogClose = () => {
  console.log("关闭弹窗");
};

/**
 * @breif: 弹窗确认按钮事件
 * @return {*}
 */
const handleDialogConfirm = async () => {
  try {
    await validateForm(diaFormDataRef.value);
    if (diaFormData.value.menuType === "1") {
      diaFormData.value.component = "Layout";
    }
    console.log(diaFormData.value);

    dialogOptions.value.openType === 1 ? await createMenuAPI(diaFormData.value) : await updateMenuAPI(diaFormData.value);
    FSMessage.success(`${dialogOptions.value.openType === 1 ? "新增成功" : "修改成功"}`);
    query();
    dialogRef.value.invisiableDialog();
  } catch (e) {
    console.log(e);
  }
};

/**
 * @breif: 表格中item编辑
 * @param {*} row
 * @return {*}
 */
const handleTableItemEdit = async (row) => {
  try {
    console.log(row);

    dialogOptions.value.openType = 2;
    dialogOptions.value.title = "编辑菜单";
    diaFormData.value = cloneDeep(row);
    dialogRef.value.visiableDialog();
  } catch (e) {
    console.log(e);
  }
};

/**
 * @breif: 表格中item删除
 * @param {*} row
 * @return {*}
 */
const handleTableItemDel = (row) => {
  try {
    FSMessage.delete().then(async () => {
      await deleteMenuAPI(row.menuId);
      FSMessage.success("删除成功");
      query();
    });
  } catch (e) {
    console.log(e);
  }
};
</script>
<style scoped lang="less">
.icon-search-container {
  margin-bottom: 20px;
}

.icon-container {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  max-height: 400px;
  overflow-y: auto;
  padding: 10px;
}

.icon-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 80px;
  height: 80px;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s;
  padding: 8px;

  &:hover {
    background-color: #f5f7fa;
    border-color: #409eff;
    color: #409eff;
  }

  .el-icon {
    font-size: 24px;
    margin-bottom: 8px;
  }

  .icon-name {
    font-size: 12px;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    width: 100%;
  }
}

.form-tip {
  font-size: 12px;
  color: #909399;
  line-height: 1.5;
  margin-top: 5px;
}
</style>
